<!-- 表单 》 日期范围 -->

<template>
  <el-form-item v-bind="formItem">
    <!-- 标签 -->
    <template v-if="hasLabelSlot" #label>
      <slot name="label" :label="formItem.label">{{ formItem.label }}</slot>
    </template>

    <el-date-picker v-model="model" v-bind="commonProps" type="daterange" @change="emitChange" />
  </el-form-item>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import dayjs from 'dayjs'
import mixForm from '../mixForm'
import FormDate from '../FormDate'

const name = 'FormDateRange'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixForm],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 选择器配置
     */
    pickerOptions: FormDate.computed.pickerOptions,

    /**
     * 成对提示
     */
    tipPair() {
      const { isDisabled, noTip } = this
      const tip = this.tip || this.label
      if (isDisabled || noTip) return ['', '']
      if (!tip) return ['开始日期', '结束日期']
      return `${tip},${tip}`.replace('，', ',').split(',').slice(0, 2)
    },

    /**
     * 公共属性
     */
    commonProps() {
      const { elProps, tipPair, size, noQuick, format, pickerOptions } = this
      return {
        ...elProps,
        name: this.prop,
        class: this.className,
        disabled: this.isDisabled,
        clearable: !this.noClear,
        size,
        defaultTime: ['00:00:00', '23:59:59'],
        startPlaceholder: tipPair[0],
        endPlaceholder: tipPair[1],
        popperClass: noQuick ? 'CoreWeb-FormPopper' : 'CoreWeb-FormPopper CoreWeb-FormPopper-quick',
        valueFormat: format ? 'yyyy-MM-dd HH:mm:ss' : 'timestamp',
        pickerOptions,
      }
    },
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 是否不等 (可覆盖)
     */
    isDiff() {
      const { obj, prop, bindList, isMulti, model, init, EMPTY, string } = this
      const values = isMulti ? [obj[bindList[0]], obj[bindList[1]]] : obj[prop]
      const begin = CORE.isArray(values) ? values[0] : EMPTY
      const end = CORE.isArray(values) ? values[1] : EMPTY
      const empty = init || [EMPTY, EMPTY]

      if (CORE.isEmpty(model)) return begin !== empty[0] || end !== empty[1]
      if (!begin || !end) return true // 由上一步的结果确定了 model 不为空
      if (string) return begin !== `${model[0]}` || end !== `${model[1]}`
      else return begin !== model[0] || end !== model[1]
    },

    /**
     * 设置内部绑定值 (可覆盖)
     */
    setModel() {
      const { obj, prop, bindList, isMulti, format } = this
      const values = isMulti ? [obj[bindList[0]], obj[bindList[1]]] : obj[prop]

      if (!CORE.isArray(values)) {
        this.model = this.init
        return
      }
      const begin = CORE.timeStr(values[0])
      const end = CORE.timeStr(values[1])
      if (!begin || !end) this.model = this.init
      else if (format) this.model = [begin, end]
      else this.model = [CORE.timeNum(begin), CORE.timeNum(end)]
    },

    /**
     * 获取最终回传值 (可覆盖)
     */
    getValue() {
      const { model, EMPTY, format, string } = this
      if (!model) return [EMPTY, EMPTY]
      if (format || !string) return model
      return [`${model[0]}`, `${model[1]}`]
    },

    /**
     * 是否物理相等 (如不等可直接用 value 赋值给 obj[bind] ) (可覆盖)
     */
    equals(value) {
      const { obj, prop, bindList, isMulti, EMPTY } = this
      const values = isMulti ? [obj[bindList[0]], obj[bindList[1]]] : obj[prop]
      const begin = CORE.isArray(values) ? values[0] : EMPTY
      const end = CORE.isArray(values) ? values[1] : EMPTY
      return begin === value[0] && end === value[1]
    },

    /**
     * 提交改变 (可覆盖)
     */
    emitChange() {
      const { obj, prop, bindList, isMulti } = this

      // 获取新值
      const value = this.getValue()

      // 判断改变
      if (this.onlyShow || this.equals(value)) return

      // 判断是否绑定的两个属性
      if (isMulti) {
        this.$set(obj, bindList[0], value[0])
        this.$set(obj, bindList[1], value[1])
      } else {
        this.$set(obj, prop, value)
      }

      // 更新事件
      this.$emit('change', value)

      // 提交之后
      this.afterEmit()
    },

    /**
     * 禁用日期
     */
    disabledDate(date) {
      const { history, future } = this
      if (!date) return false
      if (history) return date.getTime() > dayjs().endOf('day').valueOf()
      if (future) return date.getTime() < dayjs().startOf('day').valueOf()
      return false
    },
  },
}
</script>
